package com.example.foo.ftt.service;

import com.example.foo.ftt.model.FttUser;
import com.example.support.profile.ProfileHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.transaction.annotation.Transactional;

import com.example.foo.ftt.FttLevel;
import com.example.foo.ftt.FttUserException;
import com.example.foo.ftt.FttUserHelper;

@org.springframework.stereotype.Service
public class FttUserFacadeService {

	private final FttUserService fttUserService;

	public FttUserFacadeService(FttUserService fttUserService) {
		this.fttUserService = fttUserService;
	}

	// ========== FttUserFacade ==========

	@Transactional(timeout = 60, rollbackFor = Exception.class)
	public void updateFttUserState(Long id, FttUser.State state, String memo) {
		FttUser fttUser = fttUserService.findFttUserById(id);
		Long userId = fttUser.getUserId();

		if (fttUserService.findFttUserCountByParentUserId(userId) > 0) {
			throw new FttUserException("已有网体下级用户");
		}

		fttUserService.updateFttUserState(id, state, memo);

		if (state != FttUser.State.normal) {
			Long parentUserId = 0L;
			String parentUserIdPath = "/";
			fttUserService.updateFttUserParents(id, parentUserId, parentUserIdPath);
		}
	}

	public void updateFttUserParents(Long id, Long parentUserId) {
		FttUser fttUser = fttUserService.findFttUserById(id);
		if (parentUserId.equals(fttUser.getUserId())) {
			throw new FttUserException("不能归属到自己");
		}
		if (fttUser.getParentUserId() > 0) {
			throw new FttUserException("只能修改一次网体归属");
		}
		//TODO lock by parentUserId
		if (fttUserService.findFttUserCountByParentUserId(parentUserId) >= 3) {
			throw new FttUserException("该邀请码已满额，请更换邀请码");
		}
		FttUser parentFttUser = fttUserService.findFttUserByUserId(parentUserId);
		if (parentFttUser.getParentUserId() == 0 && !parentFttUser.getUserId().equals(100001L)) {
			throw new FttUserException("该邀请码没有网体归属，暂时不可用");
		}
		if (parentFttUser.getState() != FttUser.State.normal) {
			throw new FttUserException(String.format("该邀请码%s已禁止使用", parentFttUser.getReferralCode()));
		}

		String parentUserIdPath = FttUserHelper.parentUserIdPath(parentFttUser);
		fttUserService.updateFttUserParents(id, parentUserId, parentUserIdPath);
	}

	public void updateFttUserFttLevelUpgrade(Long id) {
		FttUser fttUser = fttUserService.findFttUserById(id);
		String blacklist = ProfileHelper.lookupValue("ftt.FttLevel.blacklist");
		if (blacklist != null && ArrayUtils.contains(blacklist.split(","), fttUser.getCellphone())) {
			return;
		}
		FttLevel currentFttLevel = fttUser.getFttLevel();

		List<FttUser> childFttUsers = fttUserService.findFttUsersByParentUserId(fttUser.getUserId());
		if (childFttUsers.size() < 3) {
			return;
		}

		FttLevel nextFttLevel;

		if (currentFttLevel == FttLevel.F1) {
			if (!childFttUsers.stream().allMatch(t -> t.getFttLevel().ordinal() >= FttLevel.F1.ordinal())) {
				return;
			}
			nextFttLevel = FttLevel.F2;
		} else if (currentFttLevel == FttLevel.F2
				|| currentFttLevel == FttLevel.F3
				|| currentFttLevel == FttLevel.F4
				|| currentFttLevel == FttLevel.F5
				|| currentFttLevel == FttLevel.F6
				) {
			List<FttLevel> perChildMaxFttLevels = new ArrayList<>(3);
			for (FttUser childFttUser : childFttUsers) {
				List<String> childFttLevels_s = fttUserService.findFttUserFttLevelsByParentUserIdPathLikeRight(FttUserHelper.parentUserIdPath(childFttUser));
				String childFttLevelName = childFttUser.getFttLevel().name();
				if (!childFttLevels_s.contains(childFttLevelName)) {
					childFttLevels_s.add(childFttLevelName);
				}
				List<FttLevel> childFttLevels = childFttLevels_s.stream().map(FttLevel::valueOf).collect(Collectors.toList());
				perChildMaxFttLevels.add(FttLevel.max(childFttLevels));
			}

			FttLevel minFttLevel = FttLevel.min(perChildMaxFttLevels);

			if (minFttLevel.ordinal() < currentFttLevel.ordinal()) {
				return;
			}

			FttLevel[] fttLevels = FttLevel.values();
			if ((minFttLevel.ordinal() + 1) < fttLevels.length) {
				nextFttLevel = fttLevels[minFttLevel.ordinal() + 1];
			} else {
				nextFttLevel = minFttLevel;
			}

			// {"F2":3,"F3":3,"F4":100,"F5":500,"F6":3000,"F7":30000}
			Map<String, Object> configMap = ProfileHelper.lookupValueAsMap("ftt.FttLevel.teamCount");
			Long teamCount = fttUserService.findFttUserCountByParentUserIdPathLikeRight(FttUserHelper.parentUserIdPath(fttUser));
			if (teamCount < (Integer) configMap.get(nextFttLevel.name())) {
				return;
			}
		} else if (currentFttLevel == FttLevel.F7) {
			return;
		} else {
			throw new IllegalStateException();
		}

		fttUserService.updateFttUserFttLevel(id, nextFttLevel);
	}

}
